﻿
using System;
using System.Collections.Generic;
using System.Diagnostics;
using CatEars.Core.Collections;
using CatEars.Text;

namespace CatEars.Core.Data.KvParam
{
    /// <summary>
    /// 参数对象,kv存储的基础类型
    /// </summary>
    [DebuggerDisplay("Count={Count}")]
    public abstract class ParamBase
    {
        /// <summary>
        /// 数量
        /// </summary>
        public abstract int Count { get; }

        /// <summary>
        /// 获取已有的Key
        /// </summary>
        public abstract ICollection<string> Keys { get; }

        #region 抽象方法
        /// <summary>
        /// 清空
        /// </summary>
        public abstract void Clear();
        /// <summary>
        /// 取值
        /// </summary>
        /// <param name="strKey">key</param>
        /// <param name="strDefault">默认值</param>
        /// <returns>value</returns>
        protected abstract string XGet(string strKey, string strDefault = null);

        /// <summary>
        /// 设置值
        /// </summary>
        /// <param name="strKey">key</param>
        /// <param name="strValue">value</param>
        protected abstract void XSet(string strKey, string strValue);
        #endregion

        /// <summary>
        /// 获取或设置值
        /// </summary>
        /// <param name="strKey">Key</param>
        /// <returns>Value</returns>
        public string this[string strKey]
        {
            get { return Get(strKey); }
            set { Set(strKey, value); }
        }

        /// <summary>
        /// 检查Key值是否合法
        /// </summary>
        /// <param name="strKey">Key</param>
        protected static void CheckKey(ref string strKey)
        {
            strKey = (strKey ?? "").Trim();
            if (string.IsNullOrEmpty(strKey))
            {
                throw new ArgumentException("必须指定一个非空的Key", "strKey");
            }
            //if (strKey.Contains("="))
            //{
            //    throw new ArgumentException("Key中不能含有=", "strKey");
            //}
            //if (strKey.Contains("\r") || strKey.Contains("\n"))
            //{
            //    throw new ArgumentException("Key中不能含有换行", "strKey");
            //}
        }

        #region 一般字符串
        /// <summary>
        /// 取值
        /// </summary>
        /// <param name="strKey">key</param>
        /// <param name="strDefault">默认值</param>
        /// <returns>value</returns>
        public string Get(string strKey, string strDefault = null)
        {
            CheckKey(ref strKey);
            return XGet(strKey, strDefault);
        }

        /// <summary>
        /// 设置值
        /// </summary>
        /// <param name="strKey">key</param>
        /// <param name="strValue">value</param>
        public void Set(string strKey, string strValue)
        {
            CheckKey(ref strKey);
            XSet(strKey, strValue);
        }
        #endregion

        #region 一般对象类型（非集合）
        /// <summary>
        /// 取值
        /// </summary>
        /// <param name="strKey">key</param>
        /// <param name="oDefault">默认值</param>
        /// <param name="blnThrowExc">抛出异常</param>
        /// <returns>value</returns>
        public T Get<T>(string strKey, T oDefault = default(T), bool blnThrowExc = false)
        {
            string strValue = this.Get(strKey);
            if (strValue == null)
            {
                return oDefault;
            }
            if (blnThrowExc)
            {
                return (T)Convert.ChangeType(strValue, typeof(T));
            }
            else
            {
                try
                {
                    return (T)Convert.ChangeType(strValue, typeof(T));
                }
                catch
                {
                    //忽略转换错误
                    return oDefault;
                }
            }
        }

        /// <summary>
        /// 设置值
        /// </summary>
        /// <param name="strKey">key</param>
        /// <param name="value">value</param>
        public void Set(string strKey, object value)
        {
            string strValue = null;
            if (value != null) strValue = value.ToString();
            Set(strKey, strValue);
        }
        #endregion

        #region ObjectToJson
        ///// <summary>
        ///// 取值
        ///// </summary>
        ///// <param name="strKey">key</param>
        ///// <param name="oDefault">默认值</param>
        ///// <param name="blnThrowExc">抛出异常</param>
        ///// <returns>value</returns>
        //public T GetObject<T>(string strKey, T oDefault = default(T), bool blnThrowExc = false)
        //{
        //    string strValue = this.Get(strKey);
        //    if (strValue == null)
        //    {
        //        return oDefault;
        //    }
        //    if (blnThrowExc)
        //    {
        //        return Json.ToObject<T>(strValue);
        //    }
        //    else
        //    {
        //        try
        //        {
        //            return Json.ToObject<T>(strValue);
        //        }
        //        catch
        //        {
        //            //忽略转换错误
        //            return oDefault;
        //        }
        //    }
        //}

        ///// <summary>
        ///// 设置值
        ///// </summary>
        ///// <param name="strKey">key</param>
        ///// <param name="value">value</param>
        //public void SetObject(string strKey, object value)
        //{
        //    string strValue = null;
        //    if (value != null) strValue = Json.ToJSON(value);
        //    Set(strKey, strValue);
        //}
        #endregion

        #region 集合类型
        /// <summary>
        /// 取值
        /// </summary>
        /// <param name="strKey">key</param>
        /// <param name="blnThrowExc">抛出异常</param>
        /// <returns>value</returns>
        public IEnumerable<T> GetColl<T>(string strKey, bool blnThrowExc = false)
        {
            string strValue = Get(strKey);
            if (string.IsNullOrEmpty(strValue))
            {
                return EmptyArray<T>.Array;
            }
            return StringCSE.Split<T>(strValue, ";", false, blnThrowExc);
        }

        /// <summary>
        /// 设置值
        /// </summary>
        /// <param name="strKey">key</param>
        /// <param name="coll">coll</param>
        public void SetColl<T>(string strKey, IEnumerable<T> coll)
        {
            string strValue = null;
            if (coll != null)
            {
                strValue = StringCSE.Combine(coll, ";");
            }
            Set(strKey, strValue);
        }
        #endregion

        #region 二进制类型
        /// <summary>
        /// 取值
        /// </summary>
        /// <param name="strKey">key</param>
        /// <param name="blnThrowExc">抛出异常</param>
        /// <returns>value</returns>
        public byte[] GetBytes(string strKey, bool blnThrowExc = false)
        {
            string strValue = Get(strKey);
            if (string.IsNullOrEmpty(strValue))
            {
                if (blnThrowExc)
                {
                    return Convert.FromBase64String(strValue);
                }
                else
                {
                    try
                    {
                        return Convert.FromBase64String(strValue);
                    }
                    catch { }
                }
            }
            return EmptyArray.ByteArray;
        }

        /// <summary>
        /// 设置值
        /// </summary>
        /// <param name="strKey">key</param>
        /// <param name="bytes">bytes</param>
        /// <param name="blnThrowExc">抛出异常</param>
        public void SetBytes(string strKey, byte[] bytes, bool blnThrowExc = false)
        {
            string strValue = null;
            if (bytes.HasAnyT())
            {
                strValue = Convert.ToBase64String(bytes);
            }
            Set(strKey, strValue);
        }
        #endregion
    }
}
